#include "Common.h"
#include "Render.h"
#include "SceneRenderTargets.h"
#include <iostream>

//------------------------------------------
Render::Render()
	: mD3D(NULL)
	, mD3DDevice(NULL)
	, mUseNVPerfHUD(true)
	, mVSync(false)
{
}
//------------------------------------------
Render::~Render()
{
}
//------------------------------------------
bool Render::Init(HWND hWnd)
{
    // Create the D3D object.
	mD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (mD3D == NULL)
        return false;

    // Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferCount = mVSync ? 2 : 1;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.EnableAutoDepthStencil = true;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
	d3dpp.PresentationInterval = mVSync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;

	UINT adapterIndex = D3DADAPTER_DEFAULT;
	D3DDEVTYPE deviceType = D3DDEVTYPE_HAL;
	mD3D->GetDeviceCaps(adapterIndex, deviceType, &mD3DCAPS);

	const bool bSupportsHardwareTnL = (mD3DCAPS.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? true : false;
	DWORD creationFlags = D3DCREATE_FPU_PRESERVE 
		| (bSupportsHardwareTnL ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING)
		| D3DCREATE_MULTITHREADED
		| D3DCREATE_DISABLE_DRIVER_MANAGEMENT;

	UINT adapterToUse = D3DADAPTER_DEFAULT;
	D3DDEVTYPE devType = D3DDEVTYPE_HAL;
	if (mUseNVPerfHUD)
	{
		D3DADAPTER_IDENTIFIER9 identifier;
		for (UINT adapter = 0; adapter < mD3D->GetAdapterCount(); ++adapter)
		{
			HRESULT res = mD3D->GetAdapterIdentifier(adapter,0,&identifier);
			if (strstr(identifier.Description, "PerfHUD") != 0)
			{
				adapterToUse = adapter;
				devType = D3DDEVTYPE_REF;
				creationFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
				break;
			}
		}
	}

    // Create the D3DDevice
    if (FAILED(mD3D->CreateDevice(adapterToUse, devType, hWnd, creationFlags, &d3dpp, &mD3DDevice)))
	{
		std::cerr << "Fail created the device!!!" << std::endl;
        return false;
    }

	// new the instance.
	SceneRenderTargets::NewInstance();

	return true;
}
//------------------------------------------
void Render::Exit()
{
	// release the render targets.
	SceneRenderTargets::DeleteInstance();

    if (mD3DDevice != NULL)
        mD3DDevice->Release();

    if (mD3D != NULL)
        mD3D->Release();
}
//------------------------------------------
void Render::DoRender()
{
}
//------------------------------------------
LPDIRECT3DTEXTURE9 Render::CreateTexture(int width, int height, D3DFORMAT format, bool depth)
{
	LPDIRECT3DTEXTURE9 ret;
	mD3DDevice->CreateTexture(
		width, height,
		1,
		depth ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET,
		format,
		D3DPOOL_DEFAULT,
		&ret,
		NULL);
	return ret;
}
//------------------------------------------
void Render::BeginScene()
{
	mD3DDevice->BeginScene();
}
//------------------------------------------
void Render::EndScene()
{
	mD3DDevice->EndScene();
}
//------------------------------------------